#include "SoftKey.h"
#include "../framework.h"
#include "../KeyEvent.h"
#include "../UsefullApi.h"
#include "../GuiApi.h"
#include "vmgraph.h"

static VMINT cur_softkey_hctrl;
static VMINT cur_softkey;

void SetLSKHandle(FuncPtr handle)
{
	struct control_softkey *p = (struct control_softkey*)cur_softkey_hctrl;
	
	if(handle)
	{
		p->lsk_handle = handle;
		SetKeyHandle(p->lsk_handle,KEY_LSK,KEY_EVENT_UP);
	}
}

void SetCSKHandle(FuncPtr handle)
{
	struct control_softkey *p = (struct control_softkey*)cur_softkey_hctrl;

	if(handle)
	{
		p->csk_handle = handle;
		SetKeyHandle(p->csk_handle,KEY_OK,KEY_EVENT_UP);
	}
}

void SetRSKHandle(FuncPtr handle)
{
	struct control_softkey *p = (struct control_softkey*)cur_softkey_hctrl;

	if(handle)
	{
		p->rsk_handle = handle;
		SetKeyHandle(p->rsk_handle,KEY_RSK,KEY_EVENT_UP);
	}
}

void SetSoftKeyHandle(FuncPtr lsk_handle, FuncPtr csk_handle, FuncPtr rsk_handle)
{
	SetLSKHandle(lsk_handle);
	SetCSKHandle(csk_handle);
	SetRSKHandle(rsk_handle);
}

void SetLSKLabel(VMSTR text)
{
	struct control_softkey *p = (struct control_softkey*)cur_softkey_hctrl;

	if(text)
	{
		p->lsk_label = text;
	}
}

void SetCSKLabel(VMSTR text)
{
	struct control_softkey *p = (struct control_softkey*)cur_softkey_hctrl;

	if(text)
	{
		p->csk_label = text;
	}
}

void SetRSKLabel(VMSTR text)
{
	struct control_softkey *p = (struct control_softkey*)cur_softkey_hctrl;

	if(text)
	{
		p->rsk_label = text;
	}
}

void SetSoftKeyLabel(VMSTR lsk_label, VMSTR csk_label, VMSTR rsk_label)
{
	SetLSKLabel(lsk_label);
	SetCSKLabel(csk_label);
	SetRSKLabel(rsk_label);
}

void ChangeLSKLabelHandle(FuncPtr handle, VMSTR text)
{
	SetLSKHandle(handle);
	SetLSKLabel(text);
}

void ChangeCSKLabelHandle(FuncPtr handle, VMSTR text)
{
	SetCSKHandle(handle);
	SetCSKLabel(text);
}

void ChangeRSKLabelHandle(FuncPtr handle, VMSTR text)
{
	SetRSKHandle(handle);
	SetRSKLabel(text);
}

void SetSoftkeyBackgroundImg(VMUINT8* img)
{
	struct control_softkey *p = (struct control_softkey*)cur_softkey_hctrl;

	if(img)
	{
		p->bg_img = img;
	}
}

void DrawSoftKeyRelease(VMINT hctrl)
{
	struct control_softkey *p = (struct control_softkey*)hctrl;
	VMUINT8* frame_buffer = GetHDFrameBuffer();
	VMINT x, y, width, height;

	x = p->p.p.x;
	y = p->p.p.y;
	width = p->p.p.width;
	height = p->p.p.height;
	
	vm_graphic_set_clip(x, y, x + width, y + height);

	if(p->bg_img)
	{
		DrawImageDirect(frame_buffer, p->bg_img, x, y, width, height);
	}
	else
	{
		DrawFillRect(frame_buffer, x, y, width, height, COLOR_SOFTKEY_BG, COLOR_SOFTKEY_BG);
	}
	
	DrawTextAlignment(frame_buffer, p->lsk_label, p->lsk_point.x, p->lsk_point.y, p->lsk_point.width, COLOR_SOFTKEY_TEXT, ALIGN_LEFT_MODE);
	DrawTextAlignment(frame_buffer, p->csk_label, p->csk_point.x, p->csk_point.y, p->csk_point.width, COLOR_SOFTKEY_TEXT, ALIGN_CENTER_MODE);
	DrawTextAlignment(frame_buffer, p->rsk_label, p->rsk_point.x, p->rsk_point.y, p->rsk_point.width, COLOR_SOFTKEY_TEXT, ALIGN_RIGHT_MODE);

	UpdateScreen();
}

void DrawSoftKeyPress(VMINT hctrl)
{
	struct control_softkey *p = (struct control_softkey*)hctrl;
	VMUINT8* frame_buffer = GetHDFrameBuffer();
	VMINT x, y, width, height;

	x = p->p.p.x;
	y = p->p.p.y;
	width = p->p.p.width;
	height = p->p.p.height;
	
	vm_graphic_set_clip(x, y, x + width, y + height);

	if(p->bg_img)
	{
		DrawImageDirect(frame_buffer, p->bg_img, x, y, width, height);
	}
	else
	{
		DrawFillRect(frame_buffer, x, y, width, height, COLOR_SOFTKEY_BG, COLOR_SOFTKEY_BG);
	}

	if(cur_softkey == ENUM_SOFTKEY_LSK)
	{
		DrawTextAlignment(frame_buffer, p->lsk_label, p->lsk_point.x + 1, p->lsk_point.y + 1, p->lsk_point.width, COLOR_SOFTKEY_TEXT, ALIGN_LEFT_MODE);
	}
	else
	{
		DrawTextAlignment(frame_buffer, p->lsk_label, p->lsk_point.x, p->lsk_point.y, p->lsk_point.width, COLOR_SOFTKEY_TEXT, ALIGN_LEFT_MODE);
	}

	if(cur_softkey == ENUM_SOFTKEY_CSK)
	{
		DrawTextAlignment(frame_buffer, p->csk_label, p->csk_point.x, p->csk_point.y + 1, p->csk_point.width, COLOR_SOFTKEY_TEXT, ALIGN_CENTER_MODE);
	}
	else
	{
		DrawTextAlignment(frame_buffer, p->csk_label, p->csk_point.x, p->csk_point.y, p->csk_point.width, COLOR_SOFTKEY_TEXT, ALIGN_CENTER_MODE);
	}
	
	if(cur_softkey == ENUM_SOFTKEY_RSK)
	{
		DrawTextAlignment(frame_buffer, p->rsk_label, p->rsk_point.x - 1, p->rsk_point.y + 1, p->rsk_point.width, COLOR_SOFTKEY_TEXT, ALIGN_RIGHT_MODE);
	}
	else
	{
		DrawTextAlignment(frame_buffer, p->rsk_label, p->rsk_point.x, p->rsk_point.y, p->rsk_point.width, COLOR_SOFTKEY_TEXT, ALIGN_RIGHT_MODE);
	}

	UpdateScreen();
}

void SetSoftKeyPoint(VMINT hctrl)
{
	struct control_softkey *p = (struct control_softkey*)hctrl;
	VMINT x, y, width, height;
	VMINT ch_height = vm_graphic_get_character_height();
	VMINT ch_gap_h;
	x = 0;
	width = scr_width;
	height = GetSoftkeyHeight();
	y = scr_height - height;

	ch_gap_h = (height - ch_height)/2;
	
	p->p.p.x = x;
	p->p.p.y = y;
	p->p.p.width = width;
	p->p.p.height = height;

	width = p->p.p.width/3;

	p->lsk_point.x = x + 5;
	p->lsk_point.y = y + ch_gap_h;
	p->lsk_point.width = width - 5;
	p->lsk_point.height = ch_height;

	x += width;
	p->csk_point.x = x;
	p->csk_point.y = y + ch_gap_h;
	p->csk_point.width = width;
	p->csk_point.height = ch_height;
	
	x = p->p.p.width - width;
	p->rsk_point.x = x;
	p->rsk_point.y = y + ch_gap_h;
	p->rsk_point.width = width - 5;
	p->rsk_point.height = ch_height;
}

void SoftKeyRegisterKeyHandle(VMINT hctrl)
{
	struct control_softkey *p = (struct control_softkey*)hctrl;
	if(p->lsk_handle)
	{
		SetKeyHandle(p->lsk_handle,KEY_LSK,KEY_EVENT_UP);
	}
	if(p->csk_handle)
	{
		SetKeyHandle(p->csk_handle,KEY_OK,KEY_EVENT_UP);
	}
	if(p->rsk_handle)
	{
		SetKeyHandle(p->rsk_handle,KEY_RSK,KEY_EVENT_UP);
	}
}

void TouchSoftKeyEventHandle(VMINT tevent, VMINT x, VMINT y)
{
	struct control_softkey *p = (struct control_softkey*)cur_softkey_hctrl;
	if(p->p.is_actived == FALSE)
	{
		return;
	}
	
	CHECK_IS_IN_AREA(x, y, p->lsk_point.x, p->lsk_point.y, p->lsk_point.x + p->lsk_point.width, p->lsk_point.y + p->lsk_point.height)
	{
		cur_softkey = ENUM_SOFTKEY_LSK;
	}
	CHECK_IS_IN_AREA(x, y, p->csk_point.x, p->csk_point.y, p->csk_point.x + p->csk_point.width, p->csk_point.y + p->csk_point.height)
	{
		cur_softkey = ENUM_SOFTKEY_CSK;
	}
	CHECK_IS_IN_AREA(x, y, p->rsk_point.x, p->rsk_point.y, p->rsk_point.x + p->rsk_point.width, p->rsk_point.y + p->rsk_point.height)
	{
		cur_softkey = ENUM_SOFTKEY_RSK;
	}
	
	switch(tevent)
	{
	case GUI_PEN_DOWN:
		DrawSoftKeyPress(cur_softkey_hctrl);
		break;
	case GUI_PEN_MOVE:
		DrawSoftKeyRelease(cur_softkey_hctrl);
		break;
	case GUI_PEN_UP:
		DrawSoftKeyRelease(cur_softkey_hctrl);
		switch(cur_softkey)
		{
		case ENUM_SOFTKEY_LSK:
			TouchExecKeyHandle(KEY_LSK, KEY_EVENT_UP);
			break;
		case ENUM_SOFTKEY_CSK:
			TouchExecKeyHandle(KEY_OK, KEY_EVENT_UP);
			break;
		case ENUM_SOFTKEY_RSK:
			TouchExecKeyHandle(KEY_RSK, KEY_EVENT_UP);
			break;
		}
		cur_softkey = -1;
		break;
	}
}

VMINT CreateSoftKey(VMINT is_actived, VMUINT8* bg_img, VMSTR lsk_label, VMSTR csk_label, VMSTR rsk_label)
{
	VMINT hctrl = (VMINT)vm_malloc(sizeof(struct control_softkey));
	struct control_softkey* p;

	if(hctrl == NULL)
	{
		return -1;
	}

	p = (struct control_softkey*)hctrl;
	memset(p, 0, sizeof(struct control_softkey));
	strcat(p->p.ctrl_name, "SoftKey");
	p->p.ctrl_id = DM_BOTTOM_SOFTKEY; 
	p->p.is_focused = FALSE;
	p->p.DrawStateRelease = DrawSoftKeyRelease;
	p->p.DrawStatePress = DrawSoftKeyPress;
	p->p.touch_event_handle = TouchSoftKeyEventHandle;
	p->bg_img = bg_img;
	p->p.is_actived = is_actived;
	
	cur_softkey_hctrl = hctrl;
	SetSoftKeyPoint(hctrl);
	SetSoftKeyLabel(lsk_label, csk_label, rsk_label);
	SetSoftKeyHandle(NULL, NULL, NULL);
	SetSoftkeyBackgroundImg(bg_img);
	SoftKeyRegisterKeyHandle(hctrl);

	return hctrl;
}

void FreeSoftKey(VMINT hctrl)
{
	struct control_softkey *p = (struct control_softkey*)hctrl;

	if(p->bg_img)
	{
		vm_free(p->bg_img);
		p->bg_img = NULL;
	}
	vm_free(p);
}

void ShowSoftKey(VMINT hctrl)
{
	struct control_softkey *p = (struct control_softkey*)hctrl;

	if(p->p.is_actived == FALSE)
	{
		return;
	}
	
	if(p->p.is_focused)
	{
		DrawSoftKeyPress(hctrl);
	}
	else
	{
		DrawSoftKeyRelease(hctrl);
	}
}

void RefreshSoftKey(VMINT hctrl)
{
	ShowSoftKey(hctrl);
}

void RegisterCurFocusedSoftKey(VMINT hctrl)
{
	cur_softkey_hctrl = hctrl;
}

void RedrawSoftKeyByFramework(VMINT16 keyCode, VMINT16 keyType)
{
	struct control_softkey *p = (struct control_softkey*)cur_softkey_hctrl;
	if(cur_softkey_hctrl == NULL)
	{
		return;
	}
	
	switch(keyCode)
	{
	case KEY_LSK:
		if(keyType == KEY_EVENT_DOWN)
		{
			p->p.is_focused = TRUE;
			cur_softkey = ENUM_SOFTKEY_LSK;
		}
		else if(keyType == KEY_EVENT_UP)
		{
			p->p.is_focused = FALSE;
			cur_softkey = -1;
		}
		break;
	case KEY_RSK:
		if(keyType == KEY_EVENT_DOWN)
		{
			p->p.is_focused = TRUE;
			cur_softkey = ENUM_SOFTKEY_RSK;
		}
		else if(keyType == KEY_EVENT_UP)
		{
			p->p.is_focused = FALSE;
			cur_softkey = -1;
		}
		break;
	case KEY_OK:
		if(keyType == KEY_EVENT_DOWN)
		{
			p->p.is_focused = TRUE;
			cur_softkey = ENUM_SOFTKEY_CSK;
		}
		else if(keyType == KEY_EVENT_UP)
		{
			p->p.is_focused = FALSE;
			cur_softkey = -1;
		}
		break;
	}
	
	RefreshSoftKey(cur_softkey_hctrl);
}
